package com.mashibing.mq;

import javax.jms.*;

import org.apache.activemq.ActiveMQConnectionFactory;

import java.util.ArrayList;

/**
 * 消息接受
 * @author 一明哥
 *
 *
 * 消息如果不允许重复消费的话，那要做一下 幂等
 * 给别人一个耳光和给别人一百个耳光，效果应该是一样的。
 * 啥叫幂等？ 就是一个数据扔过来，我存进DB。一百个数据扔过来，我也只存一次进DB。这就是幂等，解决重复提交或者重复消费的、
 *
 */
public class ReceiverQueue {

	public static void main(String[] args) throws Exception{

		// 1.获取连接工厂
		ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
				"admin",
				"admin",
				"tcp://localhost:61616"
				);
		//1.1、添加信任的持久化类型
        ArrayList<String> list = new ArrayList<String>();
        list.add(Girl.class.getPackage().getName());
        //这里传的是包名，
        connectionFactory.setTrustedPackages(list);
		// 2.获取一个向ActiveMQ的连接
		Connection connection = connectionFactory.createConnection();
		
		connection.start();  //这里和发送消息有点区别，这里需要start一下
		// 3.获取session
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		// 4. 找目的地，获取destination，消费端，也会从这个目的地取消息
		
		Destination queue = session.createQueue("user");
		//再开一个，专门消费死信队列
		Destination dlq = session.createQueue("ActiveMQ.DLQ");
		MessageConsumer consumer2 = session.createConsumer(dlq);
		consumer2.setMessageListener(new MessageListener() {
			@Override
			public void onMessage(Message message) {
				if(message instanceof MapMessage) {
					MapMessage mapMessage = (MapMessage)message;
					System.out.println("mapMessage-ActiveMQ.DLQ:" + mapMessage);
					try {
						System.out.println("mapMessage-ActiveMQ.DLQ:" + mapMessage.getString("name"));
						System.out.println("mapMessage-ActiveMQ.DLQ:" + mapMessage.getInt("age"));
						System.out.println("mapMessage-ActiveMQ.DLQ:" + mapMessage.getDouble("price"));
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
			}
		});

		// 5.获取消息
	
		MessageConsumer consumer = session.createConsumer(queue);

		/**
		 * 代码1又是死循环 又是阻塞，生产上是不能这么写的，万一一个消息很大产生IO阻塞了，那其他的消息就不能及时被消费 了。
		 * 代码2 写一个监听器才是优雅的处理消息的方式
		 */
		//代码2、  这里也可以写匿名类，像runnable那样
		consumer.setMessageListener(new MyListener());


		/* 代码1、//这里死循环
		for(int i=0;;i++) {
			//receive方法是阻塞的
			TextMessage message = (TextMessage)consumer.receive();
			System.out.println("-----");
			System.out.println("message2:" + message.getText());
			System.out.println("metadata:" + message);
			//这里的属性就是message的所有 元数据信息
			//ActiveMQTextMessage {commandId = 303, responseRequired = false, messageId = ID:DESKTOP-OEK4RCQ-12451-1578750463269-1:1:1:1:100, originalDestination = null, originalTransactionId = null, producerId = ID:DESKTOP-OEK4RCQ-12451-1578750463269-1:1:1:1, destination = queue://user, transactionId = TX:ID:DESKTOP-OEK4RCQ-12451-1578750463269-1:1:100, expiration = 0, timestamp = 1578750760787, arrival = 0, brokerInTime = 1578750760787, brokerOutTime = 1578750981647, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 2, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false, text = hi: 99}

			// ack代表事务中的一个操作，事务是基于session的， 不管你怎么ack，只要session不commit，那也收不到消息
            //确认了之后，消息就被删了，数据库里的记录也没了。
		//	message.acknowledge();
			// commit() //这是手动确认的方式
		//	if(i % 4 == 0)
		//		session.commit();
			
		}*/
	}
	/*
	 * 还有个问题就是receiver端createsession时是true，后面的参数为啥不会被覆盖？
	 * 
	 * 老师有点不理解，你未确认，另外一个消费者不重复消费？但你再重开消费者一个就能消费
	 */
	
}